package aa

import (
	"fmt"
	"os"
	"path/filepath"
	"sync"

	"github.com/getlantern/systray"
)

// 托盘配置
var (
	trayTitle        = "amtf-laoyu-go"
	trayTooltip      = "amtf-laoyu-go"
	iconRelativePath = "resources/logo.ico" // 相对于主程序根路径

	// 🔥 新增：退出信号通道和同步控制（确保只关闭一次）
	trayQuitChan = make(chan struct{})
	closeOnce    sync.Once // 保证channel只被关闭一次
)

// 托盘退出回调：由主程序注入，处理资源清理
var A托盘退出回调 func()

func A予托盘(回调 func(), rootPath string) {
	A托盘退出回调 = 回调
	go RunTray(rootPath)
}

// 启动托盘（阻塞，需在协程中运行）
func RunTray(rootPath string) {
	// 🔥 新增：监听退出信号，触发systray退出
	go func() {
		<-trayQuitChan
		systray.Quit()
	}()

	systray.Run(func() {
		initTrayUI(rootPath) // 初始化托盘UI
	}, func() {
		退出() // 托盘退出清理
	})
}

// 初始化托盘UI（图标、菜单）
func initTrayUI(rootPath string) {
	// 加载托盘图标
	iconPath := filepath.Join(rootPath, iconRelativePath)
	iconData, err := loadIcon(iconPath)
	if err != nil {
		fmt.Printf("⚠️ 加载托盘图标失败: %v\n", err)
	} else {
		systray.SetIcon(iconData)
	}

	// 设置托盘标题和提示
	systray.SetTitle(trayTitle)
	systray.SetTooltip(trayTooltip)

	// 创建托盘菜单
	mShow := systray.AddMenuItem("显示控制台", "显示控制台窗口")
	mHide := systray.AddMenuItem("隐藏控制台", "隐藏控制台窗口")
	systray.AddSeparator() // 分隔线
	mQuit := systray.AddMenuItem("退出", "退出程序")

	// 菜单事件监听
	go listenMenuEvents(mShow, mHide, mQuit)
}

// 监听托盘菜单点击事件
func listenMenuEvents(mShow, mHide, mQuit *systray.MenuItem) {
	for {
		select {
		case <-mShow.ClickedCh:
			fmt.Println("📌 点击【显示控制台】")
			ShowConsoleWindow()
		case <-mHide.ClickedCh:
			fmt.Println("📌 点击【隐藏控制台】")
			HideConsoleWindow()
		case <-mQuit.ClickedCh:
			fmt.Println("📌 点击【退出】")
			triggerTrayQuit() // 🔥 改为调用安全的退出触发函数
			return
		}
	}
}

// 🔥 新增：安全触发托盘退出（避免重复发送信号）
func triggerTrayQuit() {
	select {
	case trayQuitChan <- struct{}{}:
		// 成功发送退出信号
	default:
		// 通道已关闭或已有信号，忽略
	}
}

// 加载图标文件
func loadIcon(iconPath string) ([]byte, error) {
	file, err := os.Open(iconPath)
	if err != nil {
		return nil, fmt.Errorf("打开图标文件失败: %w", err)
	}
	defer file.Close()

	info, err := file.Stat()
	if err != nil {
		return nil, fmt.Errorf("获取图标文件信息失败: %w", err)
	}

	iconData := make([]byte, info.Size())
	n, err := file.Read(iconData)
	if err != nil {
		return nil, fmt.Errorf("读取图标文件失败: %w", err)
	}
	if n != int(info.Size()) {
		return nil, fmt.Errorf("图标文件读取不完整（预期%d字节，实际%d字节）", info.Size(), n)
	}
	return iconData, nil
}

// 托盘退出时的清理逻辑
func 退出() {
	fmt.Println("🔌 托盘开始退出...")
	// 🔥 确保channel只被关闭一次
	closeOnce.Do(func() {
		close(trayQuitChan)
	})

	if A托盘退出回调 != nil {
		A托盘退出回调() // 调用主程序注入的清理回调
	}
	fmt.Println("✅ 托盘已退出")
}
